﻿using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using MugenMvvmToolkit.Interfaces;

namespace MugenMvvmToolkit.Models
{
    /// <summary>
    ///  Represents the default view-model settings.
    /// </summary>
#if WPF
    [Serializable]
#endif
    [DataContract]
    public class DefaultViewModelSettings : IViewModelSettings
    {
        #region Fields

        private object _defaultBusyMessage;
        private object _validationBusyMessage;
#if WPF
        [NonSerialized]
#endif
        [XmlIgnore]
        private Func<IDictionary<object, object>> _metadataFactory;

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="DefaultViewModelSettings"/> class.
        /// </summary>
        public DefaultViewModelSettings()
        {
            _metadataFactory = () => null;
            _defaultBusyMessage = string.Empty;
            _validationBusyMessage = string.Empty;
            DisposeIocAdapter = true;
            HandleBusyMessageMode = HandleType.HandleAndNotifyListeners;
#if !NONOTIFYDATAERROR
            ErrorsChangeExecutionMode = ExecutionType.AsynchronousInUi;
#endif
        }

        #endregion

        #region Implementation of IViewModelSettings

        /// <summary>
        ///     Gets or sets property, which responsible to auto dispose container when the view model disposing.
        /// </summary>
        public bool DisposeIocAdapter { get; set; }

        /// <summary>
        ///     Gets or sets property, which responsible to auto dispose all command when the view model disposing.
        /// </summary>
        public bool DisposeCommands { get; set; }

        /// <summary>
        ///     Gets or sets the value that responsible for listen busy messages
        ///     see the <see cref="EndBusyMessage" /> and the <see cref="BeginBusyMessage" />.
        ///     <c>None</c> - not handle busy message.
        ///     <c>OneWay</c> - handle a busy message, but did not notify listeners.
        ///     <c>TwoWay</c> - handle a busy message and notify listeners.
        /// </summary>
        public HandleType HandleBusyMessageMode { get; set; }

        /// <summary>
        ///     Gets or sets value which will be displayed when invoke BeginIsBusy without message.
        /// </summary>
        public object DefaultBusyMessage
        {
            get { return _defaultBusyMessage; }
            set
            {
                Should.PropertyBeNotNull(value, "DefaultBusyMessage");
                _defaultBusyMessage = value;
            }
        }

        /// <summary>
        ///     Gets or sets value which will be displayed when invoke BeginIsBusy without message.
        /// </summary>
        public object ValidationBusyMessage
        {
            get { return _validationBusyMessage; }
            set
            {
                Should.PropertyBeNotNull(value, "ValidationBusyMessage");
                _validationBusyMessage = value;
            }
        }

        /// <summary>
        ///     Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        ///     A new object that is a copy of this instance.
        /// </returns>
        public virtual IViewModelSettings Clone()
        {
            return new DefaultViewModelSettings
            {
                DisposeCommands = DisposeCommands,
                DisposeIocAdapter = DisposeIocAdapter,
                HandleBusyMessageMode = HandleBusyMessageMode,
#if !NONOTIFYDATAERROR
                ErrorsChangeExecutionMode = ErrorsChangeExecutionMode,
#endif
                DefaultBusyMessage = DefaultBusyMessage,
                MetadataFactory = MetadataFactory
            };
        }

        #endregion

        #region Implementation of IEditorViewModelSettings

#if !NONOTIFYDATAERROR
        /// <summary>
        /// Specifies the execution mode for invoke <c>OnErrorsChanged</c> method.
        /// </summary>
        public ExecutionType ErrorsChangeExecutionMode { get; set; }
#endif

        /// <summary>
        ///     Gets or sets the validation metadata factory.
        /// </summary>
        public Func<IDictionary<object, object>> MetadataFactory
        {
            get { return _metadataFactory; }
            set
            {
                Should.PropertyBeNotNull(value, "MetadataFactory");
                _metadataFactory = value;
            }
        }

        #endregion
    }
}